package blackspire.service.character;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.springframework.transaction.annotation.Transactional;
import org.xml.sax.InputSource;

import blackspire.model.character.WOWCharacter;

@Transactional
public class CharacterServiceImpl implements CharacterService
{
	private EntityManager em;

	@PersistenceContext
	public void setEntityManager(EntityManager em)
	{
		this.em = em;
	}

	@SuppressWarnings("unchecked")
	public List<WOWCharacter> findAll()
	{
		Query query = getEntityManager().createQuery("select c FROM WOWCharacter c");
		return query.getResultList();
	}

	public void save(WOWCharacter character)
	{
		if (character.getId() == null)
		{
			// new
			em.persist(character);
		} else
		{
			// update
			em.merge(character);
		}
	}

	public void remove(int id)
	{
		WOWCharacter character = find(id);
		if (character != null)
		{
			em.remove(character);
		}
	}

	private EntityManager getEntityManager()
	{
		return em;
	}

	public WOWCharacter find(int id)
	{
		return em.find(WOWCharacter.class, id);
	}

	public WOWCharacter find(String name, String realm)
	{

		Query query = getEntityManager().createQuery("select c FROM WOWCharacter c where name = '" + name + "' and realm='" + realm + "'");

		WOWCharacter character = null;

		try
		{
			character = (WOWCharacter) query.getSingleResult();
		} catch (Exception ex)
		{

		}

		return character;

	}

	public void syncCharacterWithArmory(String name, String realm)
	{
		try
		{
			XPathFactory factory = XPathFactory.newInstance();
			XPath xPath = factory.newXPath();

			// create a singular HttpClient object
			HttpClient client = new HttpClient();

			// establish a connection within 5 seconds
			client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

			String url = "http://eu.wowarmory.com/character-sheet.xml?r=" + realm + "&n=" + name;

			// create a method object
			HttpMethod method = new GetMethod(url);
			method.setFollowRedirects(true);
			method.addRequestHeader("User-Agent", "FireFox/2.0");
			
			client.executeMethod(method);

			XPathExpression xPathExpression = null;

			// Class
			xPathExpression = xPath.compile("/page/characterInfo/character/@class");
			String characterClass = xPathExpression.evaluate(new InputSource(method.getResponseBodyAsStream()));
			
			// Level
			xPathExpression = xPath.compile("/page/characterInfo/character/@level");
			String level = xPathExpression.evaluate(new InputSource(method.getResponseBodyAsStream()));

			// Faction
			xPathExpression = xPath.compile("/page/characterInfo/character/@faction");
			String faction = xPathExpression.evaluate(new InputSource(method.getResponseBodyAsStream()));

			// Gender
			xPathExpression = xPath.compile("/page/characterInfo/character/@gender");
			String gender = xPathExpression.evaluate(new InputSource(method.getResponseBodyAsStream()));

			// Guild
			xPathExpression = xPath.compile("/page/characterInfo/character/@guild");
			String guild = xPathExpression.evaluate(new InputSource(method.getResponseBodyAsStream()));

			// Race
			xPathExpression = xPath.compile("/page/characterInfo/character/@race");
			String race = xPathExpression.evaluate(new InputSource(method.getResponseBodyAsStream()));

			WOWCharacter character = find(name, realm);

			if (character == null)
			{
				character = new WOWCharacter();
			}	
			
			character.setName(name);
			character.setRealm(realm);
			character.setCharacterclass(characterClass);
			character.setLevel(Integer.parseInt(level));
			character.setFaction(faction);
			character.setGender(gender);
			character.setGuild(guild);
			character.setRace(race);

			save(character);

		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
